package com.gjy.netty.chat;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-02-27 14:59:13
 */
public class Client {

    private static final Logger logger = LoggerFactory.getLogger(Client.class);
    private static final Integer MAX_RETRY = 10;

    public static void main(String[] args) {

        NioEventLoopGroup workGroup = new NioEventLoopGroup();

        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap
                    .group(workGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                        }
                    });
            connect(bootstrap, "localhost", 8000, 3);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            workGroup.shutdownGracefully();
        }
    }

    private static void connect(final Bootstrap bootstrap, final String host, final Integer port, int retry) throws InterruptedException {

        bootstrap.connect(host, port)
                .addListener(listener -> {
                    if (listener.isSuccess()) {
                        logger.info("连接成功");
                    } else if (retry == 0) {
                        logger.info("连接失败");
                    } else {
                        int order = (MAX_RETRY - retry) + 1;
                        int delay = 1 << order;
                        logger.info("连接失败,进行重试: {}", retry);
                        int r = retry - 1;
                        bootstrap.config().group().schedule(() -> {
                            try {
                                connect(bootstrap, host, port, r);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(e);
                            }
                        }, delay, TimeUnit.SECONDS);
//                        connect(bootstrap, host, port);
                    }
                }).channel().closeFuture().sync();
    }
}
